import logging
from functools import partial
from typing import Tuple, Type, Union

import tenacity
from botocore.exceptions import ClientError

from src.settings import RetrySettings

logger = logging.getLogger(__name__)


def create_retry(settings: RetrySettings):
    return partial(retry, settings=settings)


def retry(
    func,
    settings: RetrySettings,
    exception_type: Union[Type[Exception], Tuple[Type[Exception], ...]] = (
        FileNotFoundError,
        ClientError,
    ),
):
    return tenacity.retry(
        reraise=True,
        retry=tenacity.retry_if_exception_type(exception_type),
        stop=tenacity.stop_after_attempt(settings.attempts),
        wait=tenacity.wait_random(
            min=settings.wait_min,
            max=settings.wait_max,
        ),
        after=tenacity.after_log(logger, logging.INFO),
    )(func)
